package cn.flant.web;

import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public abstract class WebAppLoader implements ServletContextListener {
	private static WebAppLoader instance;

	public static WebAppLoader getInstance() {
		return instance;
	}

	private Set<Runnable> shutdownHookSet = new HashSet<Runnable>();
	private ServletContext servletContext;

	public void addShutdownHook(Runnable runnable) {
		synchronized (shutdownHookSet) {
			shutdownHookSet.add(runnable);
		}
	}

	public void removeShutdownHook(Runnable runnable) {
		synchronized (shutdownHookSet) {
			shutdownHookSet.remove(runnable);
		}
	}

	public ServletContext getServletContext() {
		return servletContext;
	}

	public String getInitParameter(String name) {
		return servletContext.getInitParameter(name);
	}

	public String getInitParameter(String name, String deft) {
		String value = servletContext.getInitParameter(name);
		if (value == null) {
			return deft;
		} else {
			return value;
		}
	}

	public Enumeration<String> getInitParameterNames() {
		return servletContext.getInitParameterNames();
	}

	public abstract void onStartup();

	public abstract void onShutdown();

	@Override
	public void contextInitialized(ServletContextEvent e) {
		instance = this;
		servletContext = e.getServletContext();
		onStartup();
	}

	@Override
	public void contextDestroyed(ServletContextEvent e) {
		try {
			onShutdown();
		} finally {
			synchronized (shutdownHookSet) {
				for (Runnable hook : shutdownHookSet) {
					try {
						hook.run();
					} catch (Throwable ex) {
					}
				}
				shutdownHookSet.clear();
			}
			servletContext = null;
			instance = null;
		}
	}
}
